/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package easybooking.clients.report;

import easybooking.clients.gui.*;
import easybooking.FlightManagement;
import easybooking.data.Airline;
import easybooking.data.Airport;
import easybooking.data.Booking;
import easybooking.data.Customer;
import easybooking.data.Plane;
import easybooking.data.Type;
import easybooking.data.Seat;
import easybooking.data.Flight;
import easybooking.report.AllFlightsOfCustomerReport;
import easybooking.report.AllFlightsOfCustomerWithAirlineReport;
import easybooking.report.FlightSeatingReport;
import easybooking.report.HTMLReportWriter;
import easybooking.report.PlainTextReportWriter;
import easybooking.report.ReportGenerator;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.*;

/**
 * In this Java class Client-Requests are realized as operations.
 * @author Tim Schröder
 * @author Hakan Keles
 * @author Bernd Opitz
 */
public class RCInterfaceClient {

    FlightManagement management = null;
    private String hostname;

    public RCInterfaceClient() {
    }

    /**
     * Initialises the conenction to the remote-Object "FlightManagement1" by looking up the RMI-Registry
     * @param hostname
     * @return a boolean determining if the connection was successfull
     */
    public boolean initServerConnection(String hostname) {
        this.hostname = hostname;
        String rmiRegistryServer = System.getProperty("java.rmi.registry.hostname", this.hostname);
        try {
            // Zunächst benötigen wir eine Verbindung mit einem Flight Management.
            management = (FlightManagement) Naming.lookup("rmi://" + rmiRegistryServer + ":1099/FlightManagement1");

            /*
             * Wenn wir hier ankommen, dann besteht eine Verbinung zum Server.
             * Wäre die Verbindung nicht zustande gekommen, so wäre eine
             * Exception ausgeworfen worden und das Programm wäre in den
             * entsprechenden Catch-Block (s.u.) gesprungen.
             */
            System.out.println("Verbindung hergestellt...");


        } catch (MalformedURLException murle) {
            System.out.println("MalformedURLException");
            System.out.println(murle);
            return false;
        } catch (RemoteException re) {
            System.out.println("RemoteException");
            System.out.println(re);
            return false;
        } catch (NotBoundException e) {
            System.out.println("NotBoundException");
            System.out.println(e);
            return false;
        }
        return true;
    }

    /**
     * Gets all customers from the management object
     * @return A vector containing customers.
     */
    public Vector<Customer> getAllCustomers() {
        Vector v = new Vector();
        try {
            v = management.getAllCustomers();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    public Vector<Type> getAllTypes() {
        Vector v = new Vector();
        try {
            v = management.getAllTypes();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Gets all seats from the management object
     * @return A vector containing seats.
     */
    public Vector<Seat> getAllSeats() {
        Vector v = new Vector();
        try {
            v = management.getAllSeats();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns a customer object by id
     * @param id The id of searched customer
     * @return The customer with index of <code>id</code>
     */
    public Customer findCustomerByKey(int id) {

        Customer c = null;
        try {

            c = management.getCustomerByKey(id);
            return c;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return c;
    }

    /**
     * Returns customer objects by lastname
     * @param lastName The lastname of searched customer(s)
     * @return The customer with lastname <code>lastName</code>
     */
    public Vector<Customer> findCustomerByLastName(String lastName) {

        Vector v = new Vector();
        try {
            v = management.getCustomerByLastName(lastName);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;

    }

    public Type findTypeByKey(int id) {
        Type t = null;
        try {

            t = management.findTypeByKey(id);
            return t;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return t;
    }

    /**
     * Returns type objects by name
     * @param name The name of searched type(s)
     * @return The type with name <code>name</code>
     */
    public Vector<Type> findTypeByName(String name) {
        Vector v = new Vector();
        try {
            v = management.findTypeByName(name);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns type objects by a quorum of seats inside of it
     * @param minSeats The quorum of seats
     * @return A vector containing types with a quorum of seats <code>minSeats<\code>
     */
    public Vector<Type> findTypeByMinSeatsTotal(int minSeats) {
        Vector v = new Vector();
        try {
            v = management.findTypeByMinSeatsTotal(minSeats);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns a seat object by id
     * @param id The id of searched seat
     * @return The seat with index of <code>id</code>
     */
    public Seat findSeatByKey(int id) {
        Seat s = null;
        try {

            s = management.findSeatByKey(id);
            return s;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return s;
    }

    /**
     * Returns seat objects, which are existing in a plane
     * @param p The plane object, which contains the searched seat(s)
     * @return A vector containing seats
     */
    public Vector<Seat> findSeatByPlane(Plane p) {
        Vector v = new Vector();
        try {
            v = management.findSeatByPlane(p);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns seat objects, which are existing in a plane
     * @param planeId The plane with index of <code>planeId</code>, which contains the searched seat(s)
     * @return A vector containing seats
     * @
     */
    public Vector<Seat> findSeatByPlane(int planeId) {
        Vector v = new Vector();
        try {
            v = management.findSeatByPlane(planeId);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns seat objects, which are involved in a flight
     * @param f The flight object, in which the seats are involved
     * @return A vector containing seats
     */
    public Vector<Seat> findBookedSeatByFlight(Flight f) {
        Vector v = new Vector();
        try {
            v = management.findBookedSeatByFlight(f);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns seat objects, which are involved in a flight
     * @param flighId The flight with index of <code>flightId</code>, in which the seats are involved
     * @return A vector containing seats
     */
    public Vector<Seat> findBookedSeatByFlight(int flightId) {
        Vector v = new Vector();
        try {
            v = management.findBookedSeatByFlight(flightId);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns a flight object by id
     * @param id The id of searched flight
     * @return The flight with index of <code>id</code>
     */
    public Flight findFlightByKey(int id) {
        Flight f = null;
        try {

            f = management.findFlightByKey(id);
            return f;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return f;
    }

    /**
     * Returns flight objects, which are accomplished by a plane
     * @param p The plane object, which accomplishes the flight
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByPlane(Plane p) {
        Vector v = new Vector();
        try {
            v = management.findFlightByPlane(p);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, which are accomplished by a plane
     * @param planeId The plane with index of <code>planeId</code>, which accomplishes the flight
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByPlane(int planeId) {
        Vector v = new Vector();
        try {
            v = management.findFlightByPlane(planeId);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, which are starting at an airport
     * @param a The airport object, where the searched flights are starting
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByStartAirport(Airport a) {
        Vector v = new Vector();
        try {
            v = management.findFlightByStartAirport(a);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, which are starting at an airport
     * @param startAirportId The airport with index of <code>startAirportId</code>, where the searched flights are starting
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByStartAirport(int startAirportId) {
        Vector v = new Vector();
        try {
            v = management.findFlightByStartAirport(startAirportId);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, which are destinating at an airport
     * @param a The airport object, where the searched flights are destinating
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByDestAirport(Airport a) {
        Vector v = new Vector();
        try {
            v = management.findFlightByDestAirport(a);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, which are destinating at an airport
     * @param destAirportId The airport with index of <code>destAirportId</code>, where the searched flights are destinating
     * @return A vector containing flights  
     */
    public Vector<Flight> findFlightByDestAirport(int destAirportId) {
        Vector v = new Vector();
        try {
            v = management.findFlightByDestAirport(destAirportId);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, in which a customer is involved
     * @param c The customer object, who is involved in the flight
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByCustomer(Customer c) {
        Vector v = new Vector();
        try {
            v = management.findFlightByCustomer(c);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, in which a customer is involved
     * @param customerId The customer with index of <code>customerId</code>, who is involved in a flight
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByCustomer(int customerId) {
        Vector v = new Vector();
        try {
            v = management.findFlightByCustomer(customerId);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, which is organized by an airline and in which a customer is involved
     * @param customerId The customer with index of <code>customerId</code>, who is involved in a flight
     * @param airlineId The airline with index of <code>airlineId</code>, which organizes a flight
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByCustomerAndAirline(int customerId, int airlineId) {
        Vector v = new Vector();
        try {
            v = management.findFlightByCustomerAndAirline(customerId, airlineId);

            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns flight objects, which is organized by an airline and in which a customer is involved
     * @param c The customer object, who is involved in a flight
     * @param a The airline object, which organizes a flight
     * @return A vector containing flights
     */
    public Vector<Flight> findFlightByCustomerAndAirline(Customer c, Airline a) throws RemoteException {
        Vector v = new Vector();
        try {
            v = management.findFlightByCustomerAndAirline(c, a);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Gets all airports from the management object
     * @return A vector containing airports.
     */
    public Vector<Airport> getAllAirports() {
        Vector v = new Vector();
        try {
            v = management.getAllAirports();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Creates a new Airport Object
     * @param name The name of the created airport
     * @param initials The initials of the created airport
     * @param city The city of the created airport
     */
    /**
     * Returns an airport object by id
     * @param id The id of searched airport
     * @return The airport with index of <code>id</code>
     */
    public Airport findAirportByKey(int id) {

        Airport a = null;
        try {

            a = management.findAirportByKey(id);
            return a;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return a;
    }

    /**
     * Returns airport objects by name
     * @param name The name of searched airport
     * @return The airport with name <code>name</code>
     */
    public Vector<Airport> findAirportByName(String name) {
        Vector v = new Vector();
        try {
            v = management.findAirportByName(name);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;

    }

    /**
     * Returns airport objects by initials
     * @param initials The initials of searched airport
     * @return The airport with name <code>initials</code>
     */
    public Vector<Airport> findAirportByInitials(String initials) {
        Vector v = new Vector();
        try {
            v = management.findAirportByInitials(initials);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;

    }

    /**
     * Returns airport objects by city
     * @param city The city of searched airport
     * @return The airport with city <code>city</code>
     */
    public Vector<Airport> findAirportByCity(String city) {
        Vector v = new Vector();
        try {
            v = management.findAirportByCity(city);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns airline objects by name
     * @param name The name of searched airport
     * @return The airport with name <code>name</code>
     */
    public Vector<Airline> findAirlineByName(String name) {
        Vector v = new Vector();
        try {
            v = management.findAirlineByName(name);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns airline objects by initials
     * @param initials The initials of searched airport
     * @return The airport with initials <code>initials</code>
     */
    public Vector<Airline> findAirlineByInitials(String initials) {
        Vector v = new Vector();
        try {
            v = management.findAirlineByInitials(initials);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Gets all planes from the management object
     * @return A vector containing planes.
     */
    public Vector<Plane> getAllPlanes() {

        Vector v = new Vector();
        try {
            v = management.getAllPlanes();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns Plane objects by id
     * @param id The id of searched Plane
     * @return The Plane with index <code>id</code>
     */
    public Plane findPlaneByKey(int id) {

        Plane p = null;
        try {

            p = management.findPlaneByKey(id);
            return p;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return p;
    }

    /**
     * Returns Plane objects by name
     * @param name The name of searched Plane
     * @return The Plane with name <code>name</code>
     */
    public Vector<Plane> findPlaneByName(String name) {
        Vector v = new Vector();
        try {
            v = management.findPlaneByName(name);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;

    }

    /**
     * Returns Plane objects by Type
     * @param Type The Type of searched Plane
     * @return The Planet with Type <code>Type</code>
     */
    public Vector<Plane> findPlaneByType(Type t) {
        Vector v = new Vector();
        try {
            v = management.findPlaneByType(t);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;

    }

    public Vector<Plane> findPlaneByAirline(Airline a) {
        Vector v = new Vector();
        try {
            v = management.findPlaneByAirline(a);
            return v;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;

    }

    /**
     * Gets all airlines from the management object
     * @return A vector containing airlines.
     */
    public Vector<Airline> getAllAirlines() {
        Vector v = new Vector();
        try {
            v = management.getAllAirlines();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    /**
     * Returns an airline objects by id
     * @param id The id of searched airline
     * @return The airline with index <code>id</code>
     */
    public Airline findAirlineByKey(int id) {
        Airline a = null;
        try {

            a = management.findAirlineByKey(id);
            return a;
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return a;

    }

    /**
     * Gets all flights from the management object
     * @return A vector containing flights.
     */
    public Vector<Flight> getAllFlights() {
        Vector v = new Vector();
        try {
            v = management.getAllFlights();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    public Vector<Booking> getAllBookings() {

        Vector<Booking> v = new Vector();
        try {
            v = management.getAllBookings();
        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }

    public String createFlightSeatingHtmlReport(Flight f) {
        HTMLReportWriter htmlWriter = new HTMLReportWriter();
        try {
            ReportGenerator gen = management.getReportGenerator();
            FlightSeatingReport report = gen.createFlightSeatingReport(f);
            htmlWriter.process(report);

        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        return (htmlWriter.getReportText());
    }

    public String createAllFlightsOfCustomerHtmlReport(Customer c) {
        HTMLReportWriter htmlWriter = new HTMLReportWriter();
        try {
            ReportGenerator gen = management.getReportGenerator();
            AllFlightsOfCustomerReport report = gen.createAllFlightsOfCustomerReport(c);
            htmlWriter.process(report);

        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
      return (htmlWriter.getReportText());
    }

    public String createAllFlightsOfCustomerWithArilineHtmlReport(Customer c, Airline airl) {
        HTMLReportWriter htmlWriter = new HTMLReportWriter();
        try {
            ReportGenerator gen = management.getReportGenerator();
            AllFlightsOfCustomerWithAirlineReport report = gen.createFlightsOfCustomerWithAirlineReport(c, airl);
            htmlWriter.process(report);

        } catch (RemoteException ex) {
            Logger.getLogger(RCInterfaceClient.class.getName()).log(Level.SEVERE, null, ex);
        }
      return (htmlWriter.getReportText());
    }
}
